﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AlgebraCodeFunction
{
    public class OrderType
    {
        public string name;
        public OrderType(string name, OrderType parent)
        {
            this.name = name;
            if (parent != null)
            {
                parent.subobjects[name] = this;
            }
        }

        public OrderType(string name)
        {
            this.name = name;
        }

        public Dictionary<string, OrderType> subobjects = new Dictionary<string, OrderType>();

        public Dictionary<int, Action<List<string>, OrderGlobal>> actions = new Dictionary<int, Action<List<string>, OrderGlobal>>();
        public virtual bool Implement(List<string> arg, OrderGlobal global)
        {
            Action<List<string>, OrderGlobal> func;
            if (actions.TryGetValue(arg.Count, out func))
            {
                func(arg, global);
                return true;
            }
            return false;
        }

    }

    public class OrderGlobal
    {
        public Dictionary<string, FunctionType> types = new Dictionary<string, FunctionType>();
        public Dictionary<string, Function> variables = new Dictionary<string, Function>();
        public Dictionary<string, OrderType> allOrderType = new Dictionary<string, OrderType>();

        public void Analysis(string text)
        {
            string[] sp = text.Split(' ');
            foreach (var item in sp)
            {

            }

        }

        public OrderType AddOrder(string text, OrderType orderType)
        {
            OrderType define = new OrderType(text, orderType);
            allOrderType[text] = define;
            return define;
        }
        public void Init()
        {
            OrderType define = AddOrder("define", null);
            OrderType define_type = AddOrder("define_type", define);
            OrderType define_function = AddOrder("define_function", define);
            OrderType define_function_binaryOperator = AddOrder("define_function_binaryOperator", define_function);
            define_type.actions[1] = (arg, global) =>
            {
                string name = arg[0];
                global.types[name] = new FunctionType(name);
            };

            define_type.actions[2] = (arg, global) =>
            {
                string name = arg[0];
                string parentName = arg[1];
                global.types[name] = new FunctionType(name, global.types[parentName]);
            };
            define_function_binaryOperator.actions[6] = (arg, global) =>
            {
                string typeName = arg[0];
                int priority = int.Parse(arg[1]);
                string leftAlgebraType = arg[2];
                string rightAlgebraType = arg[3];
                string returnType = arg[4];
                string parentType = arg[5];

                //string typeName, int priority, FunctionType leftAlgebraType, FunctionType rightAlgebraType, FunctionType returnType, FunctionType parentType
                global.types[typeName] = new BinaryOperatorFunctionType(typeName, priority, global.types[leftAlgebraType], global.types[rightAlgebraType], global.types[returnType], global.types[parentType]);
            };
        }

        /// <summary>
        /// 中缀表达式分析器
        /// </summary>
        List<Condition> allCondition;

        /// <summary>
        /// 中缀表达式分析器
        /// </summary>
        InfixExpressionAnalysis analysis;
        public void CompileType(string text)
        {
//            string testtext = @"
////定义类型 G
//define_type G 
//define_type func G  //定义类型 func 为函数类型
//define_function_binaryOperator + 0 G G G func //定义双目表达式函数 + 优先级0，左运算参数类型为G 右运算参数类型为G 得出的结果类型为G 该函数类型属于上一行代码定义的func类型
//define_function_binaryOperator * 1 G G G func //定义双目表达式函数 * 优先级1
//define_function_binaryOperator ^ 2 G G G func //定义双目表达式函数 ^ 优先级2
//";
            string[] vs = text.Split('\n');
            foreach (var item in vs)
            {
                string t = item.Trim();
                if (t.Length >= 2)
                {
                    string lineText = t;
                    int indexAnnotation = t.IndexOf("//");
                    if (indexAnnotation >= 0)
                    {
                        lineText = lineText.Substring(0, indexAnnotation);
                    }

                    string[] sp = lineText.Split(' ');
                    OrderType orderType;
                    int i = 0;
                    List<string> arg = new List<string>();
                    if (allOrderType.TryGetValue(sp[0], out orderType))
                    {
                        for (int j = 1; j < sp.Length; j++)
                        {
                            string v = sp[j].Trim();
                            if (!string.IsNullOrWhiteSpace(v))
                            {
                                arg.Add(v);
                                i++;
                            }
                        }
                        if (orderType.actions[i] != null)
                        {
                            orderType.actions[i](arg, this);
                        }
                    }
                }
            }

            analysis = new InfixExpressionAnalysis(types["func"]);
            //把函数类型添加到 中缀表达式分析里面去
            foreach (var item in types.Values)
            {
                if (item is BinaryOperatorFunctionType)
                {
                    analysis.binaryOperatorFunctionTypes.Add(item as BinaryOperatorFunctionType);
                }
                else
                {
                    analysis.functionTypes.Add(item);
                }
            }
        }

        public void CompileDomain(string text)
        {

//text = @"
//a+b=b+a //加法交换律
//a+(b+c)=>a+b+c //加法结合律

//a*b=b*a //乘法交换律
//a*(b*c)=>a*b*c //乘法结合律

//a*(b+c)=>a*b+a*c //加法乘法分配律
//a^(b+c)=>a^b*a^c //乘方加法分配律

//";
            allCondition = CompileDomainFunction(text, analysis);
        }
        
        public Function Run(string text)
        {
            return RunRecursion(analysis.StringToFunction(text), allCondition);//a+(e+c) "(a+b)*(c+d)"
        }

        /// <summary>
        /// 编译规则函数
        /// </summary>
        private List<Condition> CompileDomainFunction(string text, InfixExpressionAnalysis analysis)
        {
            List<Expression> allExpression = new List<Expression>();
            string[] vs = text.Split('\n');
            foreach (var item in vs)
            {
                string t = item.Trim();
                if (t.Length >= 2)
                {
                    string lineText = t;
                    int indexAnnotation = t.IndexOf("//");
                    if (indexAnnotation >= 0)
                    {
                        lineText = lineText.Substring(0, indexAnnotation);
                    }

                    int indexEqual = lineText.IndexOf("=");
                    if (indexEqual >= 0)
                    {
                        string textLeft = lineText.Substring(0, indexEqual).Trim();
                        string textRight = lineText.Substring(indexEqual + 1, lineText.Length - indexEqual - 1).Trim();

                        if (textLeft.Length > 0 && textRight.Length > 0)
                        {
                            Expression expression = new Expression();
                            if (textRight[0] == '>')
                            {
                                expression.oneWay = true;
                                textRight = textRight.Substring(1, textRight.Length - 1);
                            }
                            ConditionItem conditionItem1;
                            var funRight = analysis.StringToConditionFunction(textRight, out conditionItem1);

                            expression.conditionItemRight = conditionItem1;
                            expression.funcRight = funRight;

                            ConditionItem conditionItemLeft;
                            var funLeft = analysis.StringToConditionFunction(textLeft, out conditionItemLeft);
                            expression.conditionItemLeft = conditionItemLeft;
                            expression.funcLeft = funLeft;
                            allExpression.Add(expression);

                            expression.condition = new Condition();
                            expression.condition.mainConditionItem = conditionItemLeft;
                            expression.condition.overFunction.Add(funRight);
                        }
                    }
                }
            }

            List<Condition> allOverCondition = new List<Condition>();
            for (int i = 0; i < allExpression.Count; i++)
            {
                if (allExpression[i].oneWay)
                {
                    allExpression[i].conditionItemsDictionary[allExpression[i].funcRight.ToString()] = allExpression[i].funcRight;
                }
                else
                {
                    allExpression[i].conditionItemsDictionary[allExpression[i].funcLeft.ToString()] = allExpression[i].funcLeft;
                    allExpression[i].conditionItemsDictionary[allExpression[i].funcRight.ToString()] = allExpression[i].funcRight;
                }
                for (int j = 0; j < allExpression.Count; j++)
                {
                    if (i != j)
                    {
                        Function funcLoop;
                        if (allExpression[j].condition.IsRunRecursion(allExpression[i].funcLeft, out funcLoop))
                        {
                            List<Condition> allCondition = new List<Condition>();
                            allCondition.Add(allExpression[i].condition);
                            allCondition.Add(allExpression[j].condition);

                            var fd = 反应1(allExpression[i].funcLeft, allCondition);

                            allCondition.Clear();
                            if (allExpression[i].oneWay)
                            {
                                allCondition.Add(allExpression[i].condition);
                            }
                            if (allExpression[j].oneWay)
                            {
                                allCondition.Add(allExpression[j].condition);
                            }

                            Dictionary<string, Function> over = fd;
                            if (allCondition.Count > 0)
                            {
                                over = new Dictionary<string, Function>();
                                foreach (var item in fd.Values)
                                {
                                    var dic = 单向反应(item, allCondition);
                                    foreach (var item2 in dic)
                                    {
                                        over[item2.Key] = item2.Value;
                                    }
                                }
                            }

                            foreach (var item2 in over)
                            {
                                allExpression[i].conditionItemsDictionary[item2.Key] = item2.Value;
                            }
                            //Condition conditionLeft = new Condition();
                            //conditionLeft.mainConditionItem = allExpression[i].conditionItemLeft;
                            //conditionLeft.overFunction.AddRange(over.Values);

                            //Condition conditionRight = new Condition();
                            //conditionRight.mainConditionItem = allExpression[i].conditionItemRight;
                            //conditionRight.overFunction.AddRange(over.Values);

                            //allOverCondition.Add(conditionLeft);
                            //allOverCondition.Add(conditionRight);
                        }
                    }
                }
            }

            for (int i = 0; i < allExpression.Count; i++)
            {
                if (allExpression[i].oneWay)
                {
                    Condition conditionLeft = new Condition();
                    conditionLeft.mainConditionItem = allExpression[i].conditionItemLeft;
                    conditionLeft.overFunction.AddRange(allExpression[i].conditionItemsDictionary.Values);

                    Condition conditionRight = new Condition();
                    conditionRight.mainConditionItem = allExpression[i].conditionItemRight;
                    conditionRight.overFunction.AddRange(allExpression[i].conditionItemsDictionary.Values);

                    allOverCondition.Add(conditionLeft);
                    allOverCondition.Add(conditionRight);
                }
                else
                {
                    Condition conditionLeft = new Condition();
                    conditionLeft.mainConditionItem = allExpression[i].conditionItemLeft;
                    conditionLeft.overFunction.AddRange(allExpression[i].conditionItemsDictionary.Values);
                    allOverCondition.Add(conditionLeft);

                }

                //if (allExpression[i].oneWay)
                //{
                //    allExpression[i].conditionItemsDictionary[allExpression[i].funcRight.ToString()] = allExpression[i].funcRight;
                //}
                //else
                //{
                //    allExpression[i].conditionItemsDictionary[allExpression[i].funcLeft.ToString()] = allExpression[i].funcLeft;
                //    allExpression[i].conditionItemsDictionary[allExpression[i].funcRight.ToString()] = allExpression[i].funcRight;
                //}
            }
            return allOverCondition;
        }


        public Function RunRecursion(Function function, List<Condition> conditions)
        {
            Function f = function;
            Function root = function;
            string rootStr = root.ToString();
            bool isOk = false;
            do
            {
                rootStr = root.ToString();
                isOk = false;
                foreach (var condition in conditions)
                {
                    if (condition.IsRunRecursion(root, out f))
                    {
                        root = f;
                        isOk = true;
                    }
                }

            } while (rootStr != root.ToString());
            return root;
        }






        //public void 反应(Function function, Condition condition)
        //{
        //    Dictionary<string, Function> allFunction = new Dictionary<string, Function>();
        //    List<Function> allNow = new List<Function>() { function };
        //    do
        //    {
        //        List<Function> allNew = new List<Function>();
        //        foreach (var item in allNow)
        //        {
        //            反应2(item, condition, allFunction, allNew);
        //        }
        //        allNow = allNew;
        //    } while (allNow.Count > 0);

        //}

        public Dictionary<string, Function> 单向反应(Function mainFunction, IEnumerable<Condition> conditions)
        {
            Dictionary<string, Function> allFunction = new Dictionary<string, Function>();
            List<Function> allNow = new List<Function>() { mainFunction };

            do
            {
                List<Function> allAdd = new List<Function>();
                foreach (var condition in conditions)
                {
                    foreach (var function in allNow)
                    {
                        allAdd.AddRange(反应单个对象(function, condition));
                        foreach (var item in allAdd)
                        {
                            allFunction[item.ToString()] = item;
                        }
                        //反应2(function, condition, allFunction, allAdd);
                    }
                }
                allNow = allAdd;
                allAdd = new List<Function>();

            } while (allNow.Count > 0);

            return allFunction;
        }

        public Dictionary<string, Function> 反应1(Function mainFunction, List<Condition> conditions)
        {
            Dictionary<string, Function> allFunction = new Dictionary<string, Function>();
            List<Function> allNow = new List<Function>() { mainFunction };

            do
            {
                List<Function> allAdd = new List<Function>();
                foreach (var condition in conditions)
                {
                    foreach (var function in allNow)
                    {
                        反应2(function, condition, allFunction, allAdd);
                    }
                }
                allNow = allAdd;
                allAdd = new List<Function>();

            } while (allNow.Count > 0);

            return allFunction;
        }


        public void 反应2(Function function, Condition condition, Dictionary<string, Function> allFunction, List<Function> allAdd)
        {
            List<Function> allNow = new List<Function>() { function };
            do
            {
                List<Function> allNew = new List<Function>();
                foreach (var item in allNow)
                {
                    反应3(item, condition, allFunction, allNew);
                }
                allNow = allNew;
                allAdd.AddRange(allNew);
            } while (allNow.Count > 0);
            return;
        }

        public void 反应3(Function function, Condition condition, Dictionary<string, Function> allFunction, List<Function> allAdd)
        {
            //allFunction[function.GetToString] = function.Copy();

            Function root = function.Copy();
            List<Function> allNow = new List<Function>(); allNow.Add(root);
            //List<Function> allAdd = new List<Function>(); 

            var list = 反应单个对象(function, condition);
            foreach (var item in list)
            {
                string nameF = item.GetToString;
                if (!allFunction.ContainsKey(nameF))
                {
                    var func = item.Copy();
                    allFunction[nameF] = func;
                    allAdd.Add(func);
                }
            }

            do
            {
                List<Function> allNew = new List<Function>();
                foreach (var item in allNow)
                {
                    var newF = 反应判定(root, item, condition, allFunction);
                    if (newF != null)
                    {
                        allFunction[newF.GetToString] = newF;
                        allAdd.Add(newF);
                    }

                    for (int i = 0; i < item.ArgLength; i++)
                    {
                        var arg = item.Args[i];
                        allNew.Add(arg);
                    }
                }
                allNow = allNew;
            } while (allNow.Count > 0);

            return;
            //return allAdd;
        }

        public Function 反应判定(Function root, Function function, Condition condition, Dictionary<string, Function> allFunction)
        {
            for (int i = 0; i < function.ArgLength; i++)
            {
                var old = function.Args[i];
                var list = 反应单个对象(function.Args[i], condition);
                foreach (var item in list)
                {
                    function.SetArg(i, item);
                    string s = root.GetToString;
                    if (!allFunction.ContainsKey(s))
                    {
                        var v = root.Copy();
                        function.SetArg(i, old);
                        return v;
                    }
                    function.SetArg(i, old);
                }
            }
            return null;
        }


        /// <summary>
        /// 写到一半的坑比代码
        /// </summary>
        /// <param name="function"></param>
        /// <param name="condition"></param>
        /// <param name="allFunction"></param>
        /// <param name="allNewAdd"></param>
        public void 反应(Function function, Condition condition, Dictionary<string, Function> allFunction, List<Function> allNewAdd)
        {
            //FunctionType vFunctionType = new FunctionType("", new FunctionType[]{ function.type },  function.type , null);
            //Function functionNull = new Function("", vFunctionType);
            //functionNull.SetArg(0, function);
            List<Function> allNow = new List<Function>(function.Args);
            List<Function> allNowRoot = new List<Function>();
            List<Function> allNowParent = new List<Function>();
            List<int> allNowParentIndex = new List<int>();
            for (int i = 0; i < allNow.Count; i++)
            {
                allNowRoot.Add(function);
                allNowParent.Add(function);
                allNowParentIndex.Add(i);
            }
            //你们这些年轻人啊 不要见的风就是雨

            allFunction[function.ToString()] = function;
            do
            {
                List<Function> allNew = new List<Function>();
                List<Function> allNewRoot = new List<Function>();
                List<Function> allNewParent = new List<Function>();
                List<int> allNewParentIndex = new List<int>();
                for (int j = 0; j < allNow.Count; j++)
                {
                    var now = allNow[j];
                    var root = allNowRoot[j];
                    var parent = allNowParent[j];
                    var parentIndex = allNowParentIndex[j];
                    {
                        Function childer = null;
                        Function parentCopy = null;
                        var rootCopy = root.Copy(parent, now, ref parentCopy, ref childer);


                        var v = 反应单个对象(childer, condition);
                        foreach (var item in v)
                        {
                            parentCopy.SetArg(parentIndex, item);
                            var name = rootCopy.ToString();
                            if (!allFunction.ContainsKey(name))
                            {
                                var copy = rootCopy.Copy();
                                for (int i = 0; i < item.Args.Count; i++)
                                {
                                    allNew.Add(item[i]);
                                    allNewParent.Add(item);
                                    allNewParentIndex.Add(i);
                                    allNewRoot.Add(rootCopy);
                                    allFunction[name] = copy;
                                }
                            }
                        }
                    }


                    //for (int i = 0; i < now.ArgLength; i++)
                    //{
                    //    if (now[i] != null && now[i] is ReplaceFunction == false)
                    //    {
                    //        Function childer = null;
                    //        var parentCopy = now.Copy(now[i], ref childer);
                    //        var v = 反应单个对象(childer, condition);
                    //        foreach (var item in v)
                    //        {
                    //            parentCopy.SetArg(i, item);
                    //            var name = parentCopy.ToString();
                    //            if (!allFunction.ContainsKey(name))
                    //            {
                    //                var copy = parentCopy.Copy();
                    //                allNew.Add(copy);
                    //                allNowRoot.Add(root);
                    //                allFunction[name] = copy;
                    //            }
                    //        }
                    //    }
                    //}
                }
                allNow = allNew;
                allNowRoot = allNewRoot;
                allNowParent = allNewParent;
                allNowParentIndex = allNewParentIndex;
            } while (allNow.Count > 0);
            return;
        }

        //Function root, Function parent, int index,
        public List<Function> 反应单个对象(Function function, Condition condition)
        {
            Dictionary<string, Function> allFunction = new Dictionary<string, Function>();
            List<Function> allNew = new List<Function>();
            Function fun;
            while (condition.Run(function, out fun))
            {
                string name = fun.ToString();
                if (allFunction.ContainsKey(name))
                {
                    break;
                }
                else
                {
                    //var copy = parent.Copy();

                    allFunction[name] = fun;
                    allNew.Add(fun);
                }
            }
            return allNew;
        }

        //a=b a-b=0    a^2 + b^2 -2ab = 0  
    }

    /// <summary>
    /// 条件对象
    /// </summary>
    public class ConditionItem
    {
        public bool isVar;
        public bool isFunction;
        public FunctionType type;
        public string varName;

        public Dictionary<int, ConditionItem> conditionItems = new Dictionary<int, ConditionItem>();

        public override string ToString()
        {
            return type.ToString();
        }
    }

    /// <summary>
    /// 表达式
    /// </summary>
    public class Expression
    {
        public ConditionItem conditionItemRight;
        public Function funcRight;
        public bool oneWay = false;
        public ConditionItem conditionItemLeft;
        public Function funcLeft;
        public Condition condition;
        public Dictionary<string, Function> conditionItemsDictionary = new Dictionary<string, Function>();

    }


    public class Condition
    {
        public enum CompareEnum
        {
            /// <summary>
            /// 大于
            /// </summary>
            Greater,
            /// <summary>
            /// 等于
            /// </summary>
            Equals,
            /// <summary>
            /// 小于
            /// </summary>
            Less,
        }
        public static CompareEnum Compare(string a, string b)
        {
            char[] acs = a.ToCharArray();
            char[] bcs = b.ToCharArray();

            bool a_small = acs.Length < bcs.Length;
            int smallLength = a_small ? acs.Length : bcs.Length;

            for (int i = 0; i < smallLength; i++)
            {
                var ac = acs[i];
                var bc = bcs[i];
                if (ac == '(')
                {
                    ac = '\ufffe';
                }
                else if (ac == ')')
                {
                    ac = '\uffff';
                }
                if (bc == '(')
                {
                    bc = '\ufffe';
                }
                else if (bc == ')')
                {
                    bc = '\uffff';
                }
                if (ac < bc)
                {
                    return CompareEnum.Less;
                }
                else if (ac > bc)
                {
                    return CompareEnum.Greater;
                }
            }
            if (acs.Length == bcs.Length)
            {
                return CompareEnum.Equals;
            }
            if (a_small)
            {
                return CompareEnum.Less;
            }
            else
            {
                return CompareEnum.Greater;
            }
        }

        //public Dictionary<string, Function> variablesSource = new Dictionary<string, Function>();

        public Dictionary<string, Function> variablesRun = new Dictionary<string, Function>();

        public Function stratFunction;

        public List<Function> overFunction = new List<Function>();


        public ConditionItem mainConditionItem;

        public bool IsRunRecursion(Function function, out Function root)
        {
            Function f;
            root = function;
            bool isChange = false;
            bool isChangeFunction = false;
            string rootStr = root.ToString();
            rootStr = root.ToString();
            Stack<Function> nowList = new Stack<Function>();
            Stack<int> indexList = new Stack<int>();
            Stack<bool> isChakeList = new Stack<bool>();
            nowList.Push(root);
            indexList.Push(-1);
            isChakeList.Push(false);
            isChange = false;
            do
            {
                var now = nowList.Pop();
                int index = indexList.Pop();
                bool isChake = isChakeList.Pop();

                if (isChake)
                {
                    if (index < 0)
                    {
                        break;
                    }
                    else
                    {
                        now = nowList.Peek();
                        if (now.ArgLength > index + 1)
                        {
                            nowList.Push(now[index + 1]);
                            indexList.Push(index + 1);
                            isChakeList.Push(false);
                        }
                    }
                }
                else
                {
                    bool isRun = Run(now, out f);

                    if (isRun && now.ToString() != f.ToString())
                    {
                        isChangeFunction = true;
                        isChange = true;
                        if (index < 0)
                        {
                            root = f;
                        }
                        else
                        {
                            var p = nowList.Pop();
                            p.SetArg(index, f);
                        }
                    }
                    else
                    {
                        if (now.ArgLength > 0)
                        {
                            nowList.Push(now);
                            indexList.Push(index);
                            isChakeList.Push(true);
                            nowList.Push(now[0]);
                            indexList.Push(0);
                            isChakeList.Push(false);
                        }
                        else
                        {
                            if (index < 0)
                            {
                                break;
                            }
                            else
                            {
                                now = nowList.Peek();
                                if (now.ArgLength > index + 1)
                                {
                                    nowList.Push(now[index + 1]);
                                    indexList.Push(index + 1);
                                    isChakeList.Push(false);
                                }
                            }
                        }
                    }
                }
            } while (!isChange);

            return isChangeFunction;
        }

        public bool Run(Function function, out Function f)
        {
            variablesRun.Clear();
            if (Compare(function, mainConditionItem))
            {
                List<Function> newFunctions = new List<Function>();
                //List<List<string>> nameLists = new List<List<string>>();
                foreach (var funcItem in overFunction)
                {
                    Function newFunction = funcItem.Copy();
                    List<string> nameList = new List<string>();
                    Replace(funcItem, newFunction, nameList);
                    newFunctions.Add(newFunction);
                    //nameLists.Add(nameList);
                    //funcItem.
                }

                f = newFunctions[0];
                string minStaring = f.ToString();
                //连续比较方法 比 算逆序数的方法好
                for (int i = 1; i < newFunctions.Count; i++)
                {
                    string b = newFunctions[i].ToString();
                    CompareEnum compareEnum = Compare(minStaring, b);
                    if (compareEnum == CompareEnum.Greater)
                    {
                        f = newFunctions[i];
                        minStaring = b;
                    }
                }


                //算逆序数的方法
                /*
                int[] inversions = new int[nameLists.Count];
                for (int i = 0; i < nameLists.Count; i++)
                {
                    List<string> nameList = nameLists[i];
                    int d = 0;
                    for (int j = 0; j < nameList.Count - 1; j++)
                    {
                        for (int k = j + 1; k < nameList.Count; k++)
                        {
                            CompareEnum compareEnum = Compare(nameList[j], nameList[k]);
                            if (compareEnum == CompareEnum.Greater)
                            {
                                d++;
                            }
                        }
                    }
                    inversions[i] = d;
                }


                int min = inversions[0];
                int minIndex = 0;
                for (int i = 1; i < nameLists.Count; i++)
                {
                    if (min > inversions[i])
                    {
                        min = inversions[i];
                        minIndex = i;
                    }
                }
                f = newFunctions[minIndex];
  //              */


                return true;

            }
            f = function;
            return false;

        }

        /// <summary>
        /// 替换
        /// </summary>
        public void Replace(Function function, Function newFunc, List<string> nameList)
        {
            for (int i = 0; i < function.funcType.argCount; i++)
            {
                Function arg = function[i];
                if (arg.GetType() == typeof(ReplaceFunction))
                {
                    Function v = variablesRun[arg.name].Copy();
                    nameList.Add(v.name);
                    newFunc.SetArg(i, v);
                }
                else
                {
                    Replace(function[i], newFunc[i], nameList);
                }
            }
        }

        /// <summary>
        /// 判定条件是否符合
        /// </summary>
        /// <param name="function"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public bool Compare(Function function, ConditionItem condition)
        {
            if (condition.isVar)
            {
                Function var;
                if (variablesRun.TryGetValue(condition.varName, out var))
                {
                    return var.CompareName(function);
                }
                else
                {
                    variablesRun[condition.varName] = function;
                    return true;
                }
            }


            if (condition.isFunction)
            {
                if (function.funcType == condition.type)
                {
                    foreach (var item in condition.conditionItems)
                    {
                        if (item.Key < function.funcType.argCount && function[item.Key] != null)
                        {
                            bool isOk = Compare(function[item.Key], item.Value);
                            if (!isOk)
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                    return true;
                }
            }


            return false;
        }


        public override string ToString()
        {
            return mainConditionItem.ToString();
        }


    }





}
